package com.goodfox.web.generic.provide.interceptor;

import java.sql.Connection;
import java.util.Properties;

import org.apache.ibatis.executor.statement.PreparedStatementHandler;
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.RowBounds;

import com.goodfox.web.generic.provide.util.ReflectUtil;

@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class DiclectStatementHandlerInterceptor implements Interceptor {

	private static String dialect_type = "oracle";

	public Object intercept(Invocation invocation) throws Throwable {
		RoutingStatementHandler statement = (RoutingStatementHandler) invocation.getTarget();
		PreparedStatementHandler handler = (PreparedStatementHandler) ReflectUtil.getFieldValue(statement, "delegate");
		RowBounds rowBounds = (RowBounds) ReflectUtil.getFieldValue(handler,"rowBounds");
		if (rowBounds.getLimit()>0 && rowBounds.getLimit()<RowBounds.NO_ROW_LIMIT) {
			BoundSql boundSql = statement.getBoundSql();
			String sql = getPageSql(boundSql.getSql(),rowBounds.getOffset(),rowBounds.getLimit());
			ReflectUtil.setFieldValue(boundSql, "sql", sql);
		}
		return invocation.proceed();
	}
	
	private String getPageSql(String sql,int start,int count){  
        StringBuffer pageSql = new StringBuffer();  
        if("mysql".equals(dialect_type)){  
            pageSql.append(sql);  
            pageSql.append(" limit "+(start+1)+","+count);  
        }else if("oracle".equals(dialect_type)){  
            pageSql.append("select * from (select rownum as row_num,table_a.* from (");  
            pageSql.append(sql);  
            pageSql.append(") table_a where rownum<");  
            pageSql.append(start+count+1);  
            pageSql.append(") where row_num>=");  
            pageSql.append(start+1);  
        }  
        return pageSql.toString();  
    }  

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	public void setProperties(Properties properties) {
	}
}
